var FeedRenderer;

FeedRenderer = function () {
    var template, container, linearizeFeed, fillTemplate, formatTime,
            activeTab, settings, background, initAnchors, initRemovingAnchor,
            initRollingThumbnails, initRollingThumbnailsOnImage, instance,
            deletedVideosMemory, initAddToWatchLaterButton, watchLater;

    container = document.getElementById('feed');
    template = document.getElementById('template');
    deletedVideosMemory = new DeletedVideosMemory();
    settings = new Settings();
    background = chrome.extension.getBackgroundPage();
    background = new background.Background();
    instance = this;
    watchLater = new WatchLaterManager();

    this.render = function (feed, limit) {
        var i, code, anchors, buttons;
        if (!limit) {
            limit = settings.getDisplayedVideos();
        }
        if (!(feed instanceof Array)) {
            feed = linearizeFeed(feed);
        }
        feed = deletedVideosMemory.filterFeed(feed);
        if (settings.getSorting() == 1) {
            feed.reverse();
        }
        code = '';
        for (i = Math.min(limit, feed.length); i--;) {
            code = fillTemplate(feed[i]) + code;
        }
        if (settings.getSorting() == 1) {
            feed.reverse();
        }
        container.innerHTML = code;
        anchors = container.getElementsByTagName('a');
        initAnchors(anchors, feed, limit);
        buttons = container.getElementsByTagName('button');
        for (i = buttons.length; i--;) {
            initAddToWatchLaterButton(buttons[i]);
        }
        if (settings.getThumbCyclePeriod()) {
            initRollingThumbnails(container.getElementsByTagName('img'));
        }
    };

    /**
     * Initializes the provided button for adding a video to the "watch later"
     * playlist.
     *
     * @param {HTMLElement} button HTML button for adding a video to the
     *        "watch later" playlist.
     */
    initAddToWatchLaterButton = function (button) {
        var videoLink, videoId, inProgress, icon;
        videoLink = button.parentNode.getElementsByTagName('a')[0].href;
        videoId = videoLink.substring(videoLink.indexOf('v=') + 2);
        inProgress = false;
        icon = button.getElementsByTagName('span')[0];
        button.addEventListener('click', function () {
            var frame, interval;
            if (inProgress) {
                return;
            }
            inProgress = true;
            frame = 0;
            icon.className = 'status-icon progress progress-frame-0';
            interval = setInterval(function () {
                frame = ++frame % 12;
                icon.className = 'status-icon progress progress-frame-' +
                        frame;
            }, 45);
            button.style.display = 'initial';
            watchLater.add(videoId, function () {
                clearInterval(interval);
                icon.className = 'status-icon';
                button.className = 'success';
            }, function () {
                clearInterval(interval);
                icon.className = 'status-icon';
                button.className = 'error';
            });
        }, false);
    };

    initRollingThumbnails = function (imgs) {
        var i, id, anchor;
        for (i = imgs.length; i--;) {
            id = /\/([^/]+)\/default.jpg/.exec(imgs[i].src)[1];
            anchor = imgs[i].parentNode;
            initRollingThumbnailsOnImage(imgs[i], anchor, id);
        }
    };

    initRollingThumbnailsOnImage = function (img, anchor, id) {
        var interval;
        anchor.addEventListener('mouseover', function () {
            var i;
            i = 0;
            interval = setInterval(function () {
                img.src = 'https://i3.ytimg.com/vi/' + id + '/' + (i + 1) +
                        '.jpg';
                i = ++i % 3;
            }, settings.getThumbCyclePeriod() * 1000);
        }, false);
        anchor.addEventListener('mouseout', function () {
            clearInterval(interval);
            img.src = 'https://i2.ytimg.com/vi/' + id + '/default.jpg';
        }, false);
    };

    initAnchors = function (anchors, feed, limit) {
        var i;
        for (i = anchors.length; i--;) {
            if (!anchors[i].href) {
                initRemovingAnchor(anchors[i], feed, limit);
                continue;
            }
            anchors[i].addEventListener('click', function (e) {
                var id;
                e.preventDefault();
                if (settings.getRemoveWatched() &&
                        (this.href.indexOf('v=') > -1)) {
                    id = this.href.substring(this.href.indexOf('v=') + 2);
                    deletedVideosMemory.onVideoDeleted(id);
                    background.reload();
                }
                activeTab = background.getTabID();
                if ((e.button != 0) && settings.getMiddleClickBehaviour()) {
                    chrome.tabs.create({
                        url: this.href,
                        selected: false
                    });
                    window.close();
                    return;
                }
                if (activeTab) {
                    chrome.tabs.update(activeTab, {
                        url: this.href,
                        selected: e.button == 0
                    });
                    window.close();
                    return;
                }
                chrome.tabs.create({
                    url: this.href,
                    selected: e.button == 0
                }, function (tab) {
                    background.setTabID(tab.id);
                });
                window.close();
            }, false);
        }
    };

    initRemovingAnchor = function (anchor, feed, limit) {
        anchor.addEventListener('click', function (e) {
            var node;
            e.preventDefault();
            deletedVideosMemory.onVideoDeleted(this.id);
            background.reload();
            node = this.parentNode;
            node.parentNode.removeChild(node);
            instance.render(feed, limit);
        }, false);
    };

    fillTemplate = function (data) {
        template.getElementsByTagName('a')[0].href =
                'https://www.youtube.com/watch?v=' + data.id;
        template.getElementsByTagName('img')[0].src =
                'https://i2.ytimg.com/vi/' + data.id + '/default.jpg';
        template.getElementsByTagName('a')[1].id = data.id;
        template.getElementsByTagName('a')[2].innerText = data.title;
        template.getElementsByTagName('a')[2].href =
                'https://www.youtube.com/watch?v=' + data.id;
        template.getElementsByTagName('span')[0].innerText =
                formatTime(data.duration);
        template.getElementsByTagName('p')[0].innerText = data.description;
        template.getElementsByTagName('span')[2].innerText = data.views;
        template.getElementsByTagName('a')[3].innerText = data.uploader;
        template.getElementsByTagName('a')[3].href =
                'https://www.youtube.com/user/' + data.uploader;
        template.getElementsByTagName('span')[3].innerText = data.uploaded ?
                data.uploaded.substring(0, 10).split('-').reverse().join('. ')
                : '';
        return template.innerHTML;
    };

    linearizeFeed = function (feed) {
        var i, linear;
        linear = [];
        for (i in feed) {
            if (feed.hasOwnProperty(i)) {
                linear = linear.concat(feed[i]);
            }
        }
        return linear;
    };

    formatTime = function (time) {
        var h, m;
        h = Math.floor(time / 3600);
        time -= h * 3600;
        m = Math.floor(time / 60);
        time -= m * 60;
        h = h == 0 ? '' : h.toString() + ':';
        m = m < 10 ? '0' + m : m;
        time = time < 10 ? '0' + time : time;
        return h + m + ':' + time;
    };
};
